<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>0030: Menus V - A More Practical RadioMenuItem | gtkDcoding</title>
<meta name="generator" content="Jekyll v4.3.4" />
<meta property="og:title" content="0030: Menus V - A More Practical RadioMenuItem" />
<meta name="author" content="Ron Tarrant" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="How to use a GTK RadioMenuItem, a more practical solution - a D language tutorial." />
<meta property="og:description" content="How to use a GTK RadioMenuItem, a more practical solution - a D language tutorial." />
<link rel="canonical" href="http://localhost:4000/posts/0030-radiomenuitem-practical.html" />
<meta property="og:url" content="http://localhost:4000/posts/0030-radiomenuitem-practical.html" />
<meta property="og:site_name" content="gtkDcoding" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2019-04-26T00:00:00-04:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="0030: Menus V - A More Practical RadioMenuItem" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Ron Tarrant"},"dateModified":"2019-04-26T00:00:00-04:00","datePublished":"2019-04-26T00:00:00-04:00","description":"How to use a GTK RadioMenuItem, a more practical solution - a D language tutorial.","headline":"0030: Menus V - A More Practical RadioMenuItem","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/posts/0030-radiomenuitem-practical.html"},"url":"http://localhost:4000/posts/0030-radiomenuitem-practical.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="../assets/main.css">
  <link rel="stylesheet" href="../css/style.css" /><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="gtkDcoding" /></head>
<body><header class="site-header" role="banner">

  <div class="wrapper"><a class="site-title" rel="author" href="../">gtkDcoding</a><nav class="site-nav">
        <input type="checkbox" id="nav-trigger" class="nav-trigger" />
        <label for="nav-trigger">
          <span class="menu-icon">
            <svg viewBox="0 0 18 15" width="18px" height="15px">
              <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
            </svg>
          </span>
        </label>

        <div class="trigger"><a class="page-link" href="../about.html">About</a><a class="page-link" href="../index-reverse.html">Posts in Date Order</a><a class="page-link" href="../topics.html">Blog Posts by Topic</a></div>
      </nav></div>
</header>
<main class="page-content" aria-label="Content">
      <div class="wrapper">
        <article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
	<header class="post-header">
		<link rel="stylesheet" href="../css/font_size.css" />
		<link rel="stylesheet" href="../css/figure.css" />
		<link rel="stylesheet" href="../css/topics/menu.css" />  <!-- sub in the tag/topic -->
		<link rel="stylesheet" href="../css/modal.css" />
		<link rel="stylesheet" href="../css/post.css" />
		<link rel="stylesheet" href="../css/mascot_effects.css" />

		
		
		<p class="post-meta">
		<time class="dt-published" datetime="2019-04-26T00:00:00-04:00" itemprop="datePublished">Friday, April 26, 2019
		</time>• by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span class="p-author h-card" itemprop="name">Ron Tarrant</span></span></p>
	</header>

	<div class="post-content e-content" itemprop="articleBody">
		<div class="skew-line"></div>
		<h1 id="0030-menus-v---a-more-practical-radiomenuitem">0030: Menus V - A More Practical RadioMenuItem</h1>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img0" src="../images/screenshots/012_menus/menu_12.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal0" class="modal">																	<!-- modal# -->
				<span class="close0">&times;</span>															<!-- close# -->
				<img class="modal-content" id="img00" />															<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal0");														// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img0");															// img#
			var modalImg = document.getElementById("img00");													// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close0")[0];											// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img1" src="../images/screenshots/012_menus/menu_12_term.png" alt="Current example terminal output" />		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal1" class="modal">																				<!-- modal# -->
				<span class="close1">&times;</span>																		<!-- close# -->
				<img class="modal-content" id="img11" />																		<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal1");																	// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img1");																		// img#
			var modalImg = document.getElementById("img11");																// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close1")[0];														// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																								<!-- ------------- filename (below) --------- -->
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/012_menus/menu_12_observed_radiomenuitems.d" target="_blank">here</a>.
	</div>
</div>

<p>Today let’s look at an example that can perhaps be adapted for everyday use.</p>

<p>Herein we set a bit of data with our <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>s and track it with an observed object. And when the application terminates, it spits out a report about the state of all options in the set. This example is patterned after <a href="https://github.com/rontarrant/gtkd_demos/blob/master/012_menus/menu_10_multiple_checkmenuitems.d">the second CheckMenuItem example from two posts ago</a>, so a lot of this ground <a href="./0028-checkmenuitems.html">was covered there</a>.</p>

<p>Just a quick reminder (if you aren’t flipping back to the previous post) that we created an observed object in <code class="language-plaintext highlighter-rouge">TestRigWindow</code> which got handed down through the hierarchy. We do the same here, but because we’re dealing with <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>s and not <code class="language-plaintext highlighter-rouge">CheckMenuItem</code>s, there will be a different approach.</p>

<p>The differences are in:</p>

<ul>
  <li>how the <code class="language-plaintext highlighter-rouge">FileMenu</code> adds items,</li>
  <li>where features are turned on or off during signal-handling/callback, and</li>
  <li>(of course) we have mutual exclusivity here which we didn’t in the <code class="language-plaintext highlighter-rouge">CheckMenuItem</code> example.</li>
</ul>

<p>Let’s go through them…</p>

<h2 id="a-busier-filemenu-class">A Busier FileMenu Class</h2>

<p>Most of the differences (compared to the <code class="language-plaintext highlighter-rouge">CheckMenuItem</code> example) are in the constructor. But there are differences throughout, so let’s look at this thing in chunks:</p>

<h3 id="chunk-1">Chunk #1</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="n">FileMenu</span> <span class="p">:</span> <span class="n">Menu</span>
<span class="p">{</span>
	<span class="n">FeatureRadioMenuItem</span><span class="p">[]</span> <span class="n">featureItemArray</span><span class="p">;</span>
	<span class="n">FeatureRadioMenuItem</span> <span class="n">featureItem</span><span class="p">;</span>
	<span class="n">ExitItem</span> <span class="n">exitItem</span><span class="p">;</span>
	
	<span class="n">ListSG</span> <span class="n">group</span><span class="p">;</span>
</code></pre></div></div>

<ul>
  <li>Instead of giving each item it’s own name here, we’re creating an array (naming is deferred and we’ll see that in a moment),</li>
  <li>the <code class="language-plaintext highlighter-rouge">featureItem</code> string will serve as a temporary name within the <code class="language-plaintext highlighter-rouge">foreach</code> loop used to create the items, and</li>
  <li><code class="language-plaintext highlighter-rouge">group</code> is declared here, but will be defined during creation of the first item.</li>
</ul>

<h3 id="chunk-2">Chunk #2</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">(</span><span class="n">ObservedFeaturesList</span> <span class="n">extObservedList</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">super</span><span class="p">();</span>

	<span class="k">foreach</span><span class="p">(</span><span class="n">itemName</span><span class="p">;</span> <span class="n">extObservedList</span><span class="p">.</span><span class="n">featureNames</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">itemName</span> <span class="p">==</span> <span class="n">extObservedList</span><span class="p">.</span><span class="n">featureNames</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
		<span class="p">{</span>
			<span class="n">featureItem</span> <span class="p">=</span> <span class="k">new</span> <span class="n">FeatureRadioMenuItem</span><span class="p">(</span><span class="n">group</span><span class="p">,</span> <span class="n">extObservedList</span><span class="p">,</span> <span class="n">itemName</span><span class="p">);</span>
			<span class="n">group</span> <span class="p">=</span> <span class="n">featureItem</span><span class="p">.</span><span class="n">getGroup</span><span class="p">();</span>
		<span class="p">}</span>
		<span class="k">else</span>
		<span class="p">{</span>
			<span class="n">featureItem</span> <span class="p">=</span> <span class="k">new</span> <span class="n">FeatureRadioMenuItem</span><span class="p">(</span><span class="n">group</span><span class="p">,</span> <span class="n">extObservedList</span><span class="p">,</span> <span class="n">itemName</span><span class="p">);</span>
		<span class="p">}</span>

		<span class="n">featureItemArray</span> <span class="p">~=</span> <span class="n">featureItem</span><span class="p">;</span>
		<span class="n">append</span><span class="p">(</span><span class="n">featureItem</span><span class="p">);</span>
	<span class="p">}</span>
</code></pre></div></div>

<p>This is the first part of the constructor and includes the <code class="language-plaintext highlighter-rouge">foreach</code> loop used to create the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>s. We step through the <code class="language-plaintext highlighter-rouge">featureNames</code> string array (a part of the <code class="language-plaintext highlighter-rouge">ObservedFeatureList</code> object) to get label text for each item. The strings in <code class="language-plaintext highlighter-rouge">featureNames</code> decide the item names, and the number of strings decides how many items will be in the set.</p>

<ul>
  <li>the <code class="language-plaintext highlighter-rouge">if</code> statement takes care of the first item, the one that also defines the <code class="language-plaintext highlighter-rouge">group</code> variable,</li>
  <li>note that even though we pass the group variable to the RadioMenuItem constructor, it comes back as <code class="language-plaintext highlighter-rouge">null</code> and only takes on a value when <code class="language-plaintext highlighter-rouge">group = featureItem.getGroup()</code> is executed,</li>
  <li>the <code class="language-plaintext highlighter-rouge">else</code> statement passes the now-defined <code class="language-plaintext highlighter-rouge">group</code> along to all other items as they’re created so they become a set, and</li>
  <li>at the end of the <code class="language-plaintext highlighter-rouge">foreach</code>, we concatenate the item into our array of items before appending it to the <code class="language-plaintext highlighter-rouge">FileMenu</code>.</li>
</ul>

<h3 id="chunk-3">Chunk #3</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code>		<span class="n">extObservedList</span><span class="p">.</span><span class="n">setFeatureDefault</span><span class="p">();</span>
		
		<span class="k">foreach</span><span class="p">(</span><span class="n">item</span><span class="p">;</span> <span class="n">featureItemArray</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="n">item</span><span class="p">.</span><span class="n">getLabel</span><span class="p">()</span> <span class="p">==</span> <span class="n">extObservedList</span><span class="p">.</span><span class="n">getDefaultFeature</span><span class="p">())</span>
			<span class="p">{</span>
				<span class="n">item</span><span class="p">.</span><span class="n">setActive</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
			<span class="p">}</span>
			<span class="k">else</span>
			<span class="p">{</span>
				<span class="n">item</span><span class="p">.</span><span class="n">setActive</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
			<span class="p">}</span>
		<span class="p">}</span>

		<span class="n">exitItem</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ExitItem</span><span class="p">(</span><span class="n">extObservedList</span><span class="p">);</span>
		<span class="n">append</span><span class="p">(</span><span class="n">exitItem</span><span class="p">);</span>
		
	<span class="p">}</span> <span class="c1">// this()</span>
	
<span class="p">}</span> <span class="c1">// class FileMenu</span>
</code></pre></div></div>

<p>This part is where we set the default item and make sure the states of all items in <code class="language-plaintext highlighter-rouge">ObservedFeaturesList</code> agree with the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code> set.</p>

<p>Since these things take place in the <code class="language-plaintext highlighter-rouge">ObservedFeaturesList</code> class, we’ll cover them when we get there.</p>

<p>Finally, we drop the <code class="language-plaintext highlighter-rouge">ExitItem</code> onto the end of the menu and bail:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">exitItem</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ExitItem</span><span class="p">(</span><span class="n">extObservedList</span><span class="p">);</span>
<span class="n">append</span><span class="p">(</span><span class="n">exitItem</span><span class="p">);</span>
		
<span class="p">}</span> <span class="c1">// this()</span>
</code></pre></div></div>

<p>Now let’s look at…</p>

<h2 id="mutual-exclusion-in-the-observedfeatureslist-class">Mutual Exclusion in the ObservedFeaturesList Class</h2>

<p>Again, we’ll look at this in chunks…</p>

<h3 id="chunk-1-1">Chunk #1</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="n">ObservedFeaturesList</span>
<span class="p">{</span>
	<span class="kt">bool</span><span class="p">[</span><span class="nb">string</span><span class="p">]</span> <span class="n">features</span><span class="p">;</span>
	<span class="nb">string</span><span class="p">[]</span> <span class="n">featureNames</span><span class="p">;</span>
	<span class="nb">string</span> <span class="n">defaultFeatureName</span><span class="p">;</span>
</code></pre></div></div>

<p>These variables are:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">features</code> : an associative array with Boolean flags for tracking which item is active; text strings used as item names double as keys in the key/value pairs,</li>
  <li><code class="language-plaintext highlighter-rouge">featureNames</code> : an array of strings used to name the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>s; they do double duty when building the <code class="language-plaintext highlighter-rouge">features</code> associative array, and</li>
  <li><code class="language-plaintext highlighter-rouge">defaultFeatureName</code> : this string needs to match one of those in <code class="language-plaintext highlighter-rouge">featureNames</code> and is used to set the default item on startup.</li>
</ul>

<h3 id="chunk-2-1">Chunk #2</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">()</span>
<span class="p">{</span>
	<span class="n">defaultFeatureName</span> <span class="p">=</span> <span class="s">"Large"</span><span class="p">;</span>
	<span class="n">featureNames</span> <span class="p">=</span> <span class="p">[</span><span class="s">"Small"</span><span class="p">,</span> <span class="s">"Medium"</span><span class="p">,</span> <span class="s">"Large"</span><span class="p">,</span> <span class="s">"Extra Large"</span><span class="p">];</span>
	
<span class="p">}</span> <span class="c1">// this()</span>
</code></pre></div></div>

<p>Earlier I mentioned that the naming of <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>s is deferred. Well, this is where it’s done. All we do in the constructor is define which item will be the default and then fill in the array naming all the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>s in the set. This list can be extended or truncated to change the number of items in the set.</p>

<p><em>Note: Don’t forget to double-check that <code class="language-plaintext highlighter-rouge">defaultFeatureName</code> appears verbatim in the <code class="language-plaintext highlighter-rouge">featureNames</code> array.</em></p>

<h3 id="chunk-3-1">Chunk #3</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">setFeatureDefault</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">foreach</span><span class="p">(</span><span class="kt">ulong</span> <span class="n">i</span><span class="p">;</span> <span class="mf">0.</span><span class="p">.</span><span class="n">featureNames</span><span class="p">.</span><span class="n">length</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="nb">string</span> <span class="n">featureName</span> <span class="p">=</span> <span class="n">featureNames</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
		
		<span class="k">if</span><span class="p">(</span><span class="n">featureName</span> <span class="p">==</span> <span class="n">defaultFeatureName</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">features</span><span class="p">[</span><span class="n">featureName</span><span class="p">]</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">else</span>
		<span class="p">{</span>
			<span class="n">features</span><span class="p">[</span><span class="n">featureName</span><span class="p">]</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>

<span class="p">}</span> <span class="c1">// setFeatureDefault()</span>
</code></pre></div></div>

<p>This is the function called from <code class="language-plaintext highlighter-rouge">FileMenu</code>’s constructor, the one that—as the name implies—sorts out which <code class="language-plaintext highlighter-rouge">RadioMenuItem</code> will be turned on by default.</p>

<p>Note: I just wanna point out the <em>D</em>-ness of the <code class="language-plaintext highlighter-rouge">foreach()</code> construct. A number of languages use <code class="language-plaintext highlighter-rouge">foreach()</code> for looping, but <em>D</em>’s syntax—if you’ve never seen it before—is worth a pause to take it in. It breaks down as:</p>

<p><code class="language-plaintext highlighter-rouge">foreach(</code><type> <increment>`;` <start-of-range>`..`<end-of-range>`)`</end-of-range></start-of-range></increment></type></p>

<p>If you were to write the above loop with <code class="language-plaintext highlighter-rouge">for()</code>, your incrementing variable would be an integer. But with <code class="language-plaintext highlighter-rouge">foreach()</code>, any time you increment along the length of an array, <code class="language-plaintext highlighter-rouge">i</code> has to be a <code class="language-plaintext highlighter-rouge">ulong</code>.</p>

<h3 id="chunk-4">Chunk #4</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">setFeature</span><span class="p">(</span><span class="nb">string</span> <span class="n">featureName</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">foreach</span><span class="p">(</span><span class="n">feature</span><span class="p">,</span> <span class="n">state</span><span class="p">;</span> <span class="n">features</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">feature</span> <span class="p">==</span> <span class="n">featureName</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">features</span><span class="p">[</span><span class="n">feature</span><span class="p">]</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">else</span>
		<span class="p">{</span>
			<span class="n">features</span><span class="p">[</span><span class="n">feature</span><span class="p">]</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	
<span class="p">}</span> <span class="c1">// setFeature()</span>
</code></pre></div></div>

<p>When an item in the set is selected by the user, this function is called by the callback to keep the <code class="language-plaintext highlighter-rouge">ObservedFeaturesList</code> in sync with the state of the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code> set.</p>

<h3 id="chunk-5">Chunk #5</h3>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code>	<span class="nb">string</span> <span class="n">getDefaultFeature</span><span class="p">()</span>
	<span class="p">{</span>
		<span class="k">return</span><span class="p">(</span><span class="n">defaultFeatureName</span><span class="p">);</span>
	<span class="p">}</span>	
	
	
	<span class="kt">bool</span> <span class="n">getFeature</span><span class="p">(</span><span class="nb">string</span> <span class="n">featureName</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">return</span><span class="p">(</span><span class="n">features</span><span class="p">[</span><span class="n">featureName</span><span class="p">]);</span>
		
	<span class="p">}</span> <span class="c1">// getFeature()</span>
	
	
	<span class="kt">void</span> <span class="n">listFeatures</span><span class="p">()</span>
	<span class="p">{</span>
		<span class="k">foreach</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">feature</span><span class="p">;</span> <span class="n">features</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">writeln</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s">" = "</span><span class="p">,</span> <span class="n">feature</span><span class="p">);</span>
		<span class="p">}</span>
		
	<span class="p">}</span> <span class="c1">// listFeatures()</span>
	
<span class="p">}</span> <span class="c1">// class ObservedFeaturesList</span>
</code></pre></div></div>

<p>These functions do the following:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">getDefaultFeature() </code>is called from the second half of <code class="language-plaintext highlighter-rouge">FileMenu</code>’s constructor to sync up the flags in the <code class="language-plaintext highlighter-rouge">features</code> associative array with the state of the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code> set, and</li>
  <li><code class="language-plaintext highlighter-rouge">getFeatureState()</code> is unused in this example, but is here as a placeholder. It returns the Boolean value of the named feature. It can be tested like this (perhaps from somewhere near the end of the <code class="language-plaintext highlighter-rouge">setFeature()</code> function):</li>
</ul>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">writeln</span><span class="p">(</span><span class="s">"The state of "</span><span class="p">,</span> <span class="n">featureName</span><span class="p">,</span> <span class="s">": "</span><span class="p">,</span> <span class="n">getFeatureState</span><span class="p">(</span><span class="n">featureName</span><span class="p">));</span>
</code></pre></div></div>

<h2 id="and-finally-the-featureradiomenuitem-class">And Finally: the FeatureRadioMenuItem Class</h2>

<p>This is a lot of stuff we’ve seen before, but one thing I’d like to point out is this: The callback is triggered whether the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code> is going into an <em>on</em> state or an <em>off</em> state. That’s why there’s also an <code class="language-plaintext highlighter-rouge">if</code> statement in there to test the state of the <code class="language-plaintext highlighter-rouge">RadioMenuItem</code>. I would assume you could also have an <code class="language-plaintext highlighter-rouge">else</code> for doing some type of clean-up or what-have-you when an item is deselected.</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="n">FeatureRadioMenuItem</span> <span class="p">:</span> <span class="n">RadioMenuItem</span>
<span class="p">{</span>
	<span class="nb">string</span> <span class="n">labelText</span><span class="p">;</span>
	<span class="n">ObservedFeaturesList</span> <span class="n">observedList</span><span class="p">;</span>
   
	<span class="k">this</span><span class="p">(</span><span class="n">ListSG</span> <span class="n">group</span><span class="p">,</span> <span class="n">ObservedFeaturesList</span> <span class="n">extObservedList</span><span class="p">,</span> <span class="nb">string</span> <span class="n">extLabelText</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">labelText</span> <span class="p">=</span> <span class="n">extLabelText</span><span class="p">;</span>
		<span class="k">super</span><span class="p">(</span><span class="n">group</span><span class="p">,</span> <span class="n">labelText</span><span class="p">);</span>

		<span class="n">observedList</span> <span class="p">=</span> <span class="n">extObservedList</span><span class="p">;</span>
		<span class="n">addOnToggled</span><span class="p">(&amp;</span><span class="n">toggleFeature</span><span class="p">);</span>
		
	<span class="p">}</span> <span class="c1">// this()</span>
	
	
	<span class="kt">void</span> <span class="n">toggleFeature</span><span class="p">(</span><span class="n">CheckMenuItem</span> <span class="n">mi</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">getActive</span><span class="p">()</span> <span class="p">==</span> <span class="kc">true</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">observedList</span><span class="p">.</span><span class="n">setFeature</span><span class="p">(</span><span class="n">labelText</span><span class="p">);</span>
		<span class="p">}</span>
		
	<span class="p">}</span> <span class="c1">// toggleFeature()</span>
	
<span class="p">}</span> <span class="c1">// class FeatureRadioMenuItem</span>
</code></pre></div></div>

<p>We could also have used the <code class="language-plaintext highlighter-rouge">onActivate</code> signal instead of <code class="language-plaintext highlighter-rouge">onToggled</code>, but the results are pretty much the same either way.</p>

<p>Now, since this looks to be the longest blog post I’ve done to date, pay no attention while I beat a hasty exit, stage right.</p>

<div class="blog-nav">
	<div style="float: left;">
		<a href="./0029-radiomenuitem.html">Previous: RadioMenuItem</a>
	</div>
	<div style="float: right;">
		<a href="./0031-imagemenuitem.html">Next: ImageMenuItem</a>
	</div>
</div>
<p>
	<h3></h3>
<div class="inpage-frame">
	<a href="https://github.com/sponsors/rontarrant">
		<BR>
		<BR>
		<B>Is this article useful? Educational? Entertaining, perhaps?</B>
		<BR>
		<figure class="left">
			<img src="../images/favorite_32.png" alt="Sponsorship heart" style="width: 32px; height: 32px;">
		</figure>
		You're free to accept or decline this invitation to become our newest sponsor.
	</a>
</div>
	<h4 class="comment-blurb"><B>Comments? Questions? Observations?</B></h4>
	<p>
		Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.
	</p>
	<script src="https://utteranc.es/client.js"
		repo="rontarrant"
		issue-term="pathname"
		theme="github-light"
		crossorigin="anonymous"
		async>
	</script>
	<ul>
		<li> come on over to the <a href="https://forum.dlang.org/">D Language Forum</a> and look for one of the <i>gtkDcoding</i> announcement posts, </li>
		<li> drop by <a href="https://forum.gtkd.org/">the <i>GtkD Forum</i></a>,</li>
		<li> follow the link below to email me, or</li>
		<li> go to the	<a href="https://www.facebook.com">gtkDcoding Facebook page.</a></li>
	</ul>
</p>
<p> You can also subscribe <a href="/feed.xml">via RSS</a> so you won't miss anything. Thank you very much for dropping by.</p>
<p>&copy; Copyright 2025 Ron Tarrant </p>
</div>

	<a class="u-url" href="./0030-radiomenuitem-practical.html" hidden></a>
</article>

      </div>
    </main><footer class="site-footer h-card">
  <data class="u-url" href="/"></data>

  <div class="wrapper">

    <h2 class="footer-heading">gtkDcoding</h2>

    <div class="footer-col-wrapper">
      <div class="footer-col footer-col-1">
        <ul class="contact-list">
          <li class="p-name">Ron Tarrant</li><li><a class="u-email" href="mailto:gtkDcoding@gmail.com">gtkDcoding@gmail.com</a></li></ul>
      </div>

      <div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/rontarrant"><svg class="svg-icon"><use xlink:href="../assets/minima-social-icons.svg#github"></use></svg> <span class="username">rontarrant</span></a></li></ul>
</div>

      <div class="footer-col footer-col-3">
        <p>Simple examples of how to use GtkD to build GUI applications.</p>
      </div>
    </div>

  </div>

</footer>
</body>

</html>
